#include <iostream>
#include <cmath>

#include "Framebuffer.h"
#include "Vector.h"
#include "Ray.h"
#include "Sphere.h"
#include "Triangle.h"

using namespace std;

Sphere s = Sphere(Vector(400,300,-10), 100);
Triangle t = Triangle(Vector(600,400,-10),Vector(800,400,-10),Vector(600,200,-10));
Ray r = Ray();
ColorRGBA white = ColorRGBA(1.0f,1.0f,1.0f,1.0f);

float FalsePattern1(ui32 x, ui32 y)
{
  // Box-Filter sample position
  float _x=(float)x-0.5f,
        _y=(float)y-0.5f;
  // sample function point
  return (sin(_x+_y*_x*3.145f) / 10.0f);
}

float FalsePattern2(ui32 x, ui32 y)
{
  // Box-Filter sample position
  float _x=(float)x-0.5f,
        _y=((float)y/10.0f)-0.5f;
  // sample function point
  return (sin(_x+_y*_x*3.145f) / 10.0f);
}

float FalsePattern3(ui32 x, ui32 y)
{
  // Box-Filter sample position
  float _x=(float)x-0.5f,
        _y=(float)y-0.5f;
  // sample function point
  return (0.5f * (1.0f + sin((_x*_x+_y*_y)/100.0f)));
}

void Trace(const ui32 x, const ui32 y, ColorRGBA& c)
{
  r.o.x = (fp)x;
  r.o.y = (fp)y;
  
  if (s.Intersect(r) == true ||
      t.Intersect(r) == true) c.Set(white);
};

i32 chosenPattern = 0;

void Pattern(const ui32 x, const ui32 y, ColorRGBA& c)
{
  switch (chosenPattern)
  {
    case 0: c.r=c.g=c.b=FalsePattern1(x,y); break;
    case 1: c.r=c.g=c.b=FalsePattern2(x,y); break;
    case 2: c.r=c.g=c.b=FalsePattern3(x,y); break;
  }; 
};

i32 main()
{
  Framebuffer f = Framebuffer();
  i32 slot = f.Create(1280,720);

  f.Register(slot, &Trace);
  f.Process(slot);

  f.Write(slot, "trace");

  f.Register(slot, &Pattern);
  for (ui32 p = 0; p < 3; p++)
  {
    chosenPattern = p;
    f.Process(slot);
    
    switch(p)
    {
      case 0: f.Write(slot, "falsePattern1"); break;
      case 1: f.Write(slot, "falsePattern2"); break;
      case 2: f.Write(slot, "falsePattern3"); break;
    }
  };
  
  return 0;
}
